package com.geely.club.util.openapiclient;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import cn.evun.gap.openapi.client.binding.RopClientException;
import cn.evun.gap.openapi.client.binding.ServiceMethod;
import cn.evun.gap.openapi.client.binding.ServiceMethodDefinition;
import cn.evun.gap.openapi.client.model.openapi.ServiceMethodParam;
import cn.evun.gap.openapi.client.utils.StringUtils;

/**
 * Created by mengyangyang on 2015-10-15.
 */
public class ServiceRegistry extends cn.evun.gap.openapi.client.binding.ServiceRegistry {

    private final Map<Method, ServiceMethodDefinition> methodDefinitionMap = new HashMap<Method, ServiceMethodDefinition>();

    private OpenApiClient openApiClient;

    public void setOpenApiClient(OpenApiClient openApiClient) {
        this.openApiClient = openApiClient;
    }

    public <T> T getService(Class<T> type) {
        try {
            return ServiceProxy.newMapperProxy(type, this, openApiClient);
        } catch (Exception e) {
            throw new RopClientException("Error getting mapper instance. Cause: " + e, e);
        }
    }

    public ServiceMethodDefinition getServiceMethodDefinition(Method method) {
        return methodDefinitionMap.get(method);
    }

    public boolean hasServiceMethodDefinition(Method method) {
        return methodDefinitionMap.containsKey(method);
    }

    public ServiceMethodDefinition addServiceMethodDefinition(Method method, ServiceMethodParam serviceMethodParam) {

        ServiceMethod serviceMethod = method.getAnnotation(ServiceMethod.class);

        if (null == serviceMethod) {
            throw new RopClientException("service method no ServiceMethod Annotation, please checked!");
        }

        ServiceMethodDefinition serviceMethodDefinition = new ServiceMethodDefinition();

        serviceMethodDefinition.setMethod(serviceMethod.method());

        serviceMethodDefinition.setVersion(serviceMethod.v());

        serviceMethodDefinition.setOldVersion(serviceMethod.v());

        serviceMethodDefinition.setAction(serviceMethod.action());

        serviceMethodDefinition.setOldAction(serviceMethod.action());

        if (null != serviceMethodParam.getAction()) {
            serviceMethodDefinition.setAction(serviceMethodParam.getAction());
        }
        if (!StringUtils.isEmpty(serviceMethodParam.getV())) {
            serviceMethodDefinition.setVersion(serviceMethodParam.getV());
        }

        serviceMethodDefinition.setTicket(serviceMethodParam.getTicket());

        this.methodDefinitionMap.put(method, serviceMethodDefinition);

        return serviceMethodDefinition;
    }
}
